package com.meiyuetao.myt.md.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import lab.s2jh.core.dao.BaseDao;
import lab.s2jh.core.service.BaseService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import com.google.common.collect.Lists;
import com.meiyuetao.myt.md.dao.CategoryDao;
import com.meiyuetao.myt.md.entity.Category;
import com.meiyuetao.myt.md.entity.Category.CategoryEnum;

@Service
@Transactional
public class CategoryService extends BaseService<Category, Long> {

    @Autowired
    private CategoryDao categoryDao;

    @Override
    protected BaseDao<Category, Long> getEntityDao() {
        return categoryDao;
    }

    @Transactional(readOnly = true)
    @Cacheable(value = "MytCategorySpringCache", key = "#root.methodName")
    public List<Category> findLabels() {
        List<Category> categories = Lists.newArrayList();
        List<Category> allItems = categoryDao.findAllCached();
        for (Category category : allItems) {
            if (CategoryEnum.LABEL.equals(category.getCategoryType()) && category.getCategoryLevel() == 2) {
                categories.add(category);
            }
        }
        return categories;
    }

    @Transactional(readOnly = true)
    @Cacheable(value = "MytCategorySpringCache", key = "#root.methodName")
    public List<Category> findTimelines() {
        List<Category> categories = Lists.newArrayList();
        List<Category> allItems = categoryDao.findAllCached();
        for (Category category : allItems) {
            if (CategoryEnum.TIMELINE.equals(category.getCategoryType())) {
                categories.add(category);
            }
        }
        Collections.sort(categories);
        return categories;
    }

    @Transactional(readOnly = true)
    @Cacheable(value = "MytCategorySpringCache", key = "#root.methodName")
    public List<Category> findRootCategories(CategoryEnum categoryType) {
        Assert.notNull(categoryType);
        List<Category> categories = Lists.newArrayList();
        List<Category> allItems = categoryDao.findAllCached();
        for (Category category : allItems) {
            if (categoryType.equals(category.getCategoryType()) && category.getCategoryLevel() == 1) {
                categories.add(category);
            }
        }
        Collections.sort(categories);
        return categories;
    }

    @Transactional(readOnly = true)
    @Cacheable(value = "MytCategorySpringCache", key = "{#root.methodName, #parent?.id}")
    public List<Category> findChildren(Category parent) {
        if (parent == null) {
            return findRootCategories(CategoryEnum.CATEGORY);
        }
        List<Category> categories = new ArrayList<Category>();
        List<Category> allItems = categoryDao.findAllCached();
        for (Category category : allItems) {
            if (parent.equals(category.getParent())) {
                categories.add(category);
            }
        }
        Collections.sort(categories);
        return categories;
    }

    @Override
    @CacheEvict(value = "MytCategorySpringCache", allEntries = true)
    public Category save(Category entity) {
        return super.save(entity);
    }

    @Override
    @CacheEvict(value = "MytCategorySpringCache", allEntries = true)
    public void delete(Category entity) {
        super.delete(entity);
    }

    @Override
    @CacheEvict(value = "MytCategorySpringCache", allEntries = true)
    public List<Category> save(Iterable<Category> entities) {
        return super.save(entities);
    }

    @Override
    @CacheEvict(value = "MytCategorySpringCache", allEntries = true)
    public void delete(Iterable<Category> entities) {
        super.delete(entities);
    }
}
